<script lang="ts" setup>
import { nextTick, reactive, ref } from 'vue';
import { type ElMessageBoxOptions, ElMessageBox, ElMessage } from 'element-plus';
import { deleteTableDataApi, getTableDataApi } from '@/api/table';
import { type GetTableResponseData } from '@/api/table/types/table';
import RoleColumnSolts from './tsx/RoleColumnSolts';
import StatusColumnSolts from './tsx/StatusColumnSolts';
import {
	type VxeGridInstance,
	type VxeGridProps,
	type VxeModalInstance,
	type VxeModalProps,
	type VxeFormInstance,
	type VxeFormProps,
} from 'vxe-table';
// 引入路由监听器
import { useRouteListener } from '@/hooks/useRouteListener';
import { type RouteLocationNormalized } from 'vue-router';

const { listenerRouteChange } = useRouteListener();
// 添加路由监听器，这里假设 `handleRouteChange` 是你的回调函数
const handleRouteChange = (route: RouteLocationNormalized) => {
	console.log('Route changed to:', route);
	// 执行与路由变化相关的操作
};
// 立即执行并监听路由变化
listenerRouteChange(handleRouteChange, true);

defineOptions({
	// 命名当前组件
	name: 'VxeTable',
});

//#region vxe-grid
interface RowMeta {
	id: string;
	username: string;
	roles: string;
	phone: string;
	email: string;
	status: boolean;
	createTime: string;
	/** vxe-table 自动添加上去的属性 */
	_VXE_ID?: string;
}
const xGridDom = ref<VxeGridInstance>();
const xGridOpt: VxeGridProps = reactive({
	loading: true,
	autoResize: true,
	/** 分页配置项 */
	pagerConfig: {
		align: 'right',
	},
	/** 表单配置项 */
	formConfig: {
		items: [
			{
				field: 'username',
				itemRender: {
					name: '$input',
					props: { placeholder: '用户名', clearable: true },
				},
			},
			{
				field: 'phone',
				itemRender: {
					name: '$input',
					props: { placeholder: '手机号', clearable: true },
				},
			},
			{
				itemRender: {
					name: '$buttons',
					children: [
						{
							props: { type: 'submit', content: '查询', status: 'primary' },
						},
						{
							props: { type: 'reset', content: '重置' },
						},
					],
				},
			},
		],
	},
	/** 工具栏配置 */
	toolbarConfig: {
		refresh: true,
		custom: true,
		slots: { buttons: 'toolbar-btns' },
	},
	/** 自定义列配置项 */
	customConfig: {
		/** 是否允许列选中  */
		checkMethod: ({ column }) => !['username'].includes(column.field),
	},
	/** 列配置 */
	columns: [
		{
			type: 'checkbox',
			width: '50px',
		},
		{
			field: 'username',
			title: '用户名',
		},
		{
			field: 'roles',
			title: '角色',
			/** 自定义列与 type: "html" 的列一起使用，会产生错误，所以采用 TSX 实现 */
			slots: RoleColumnSolts,
		},
		{
			field: 'phone',
			title: '手机号',
		},
		{
			field: 'email',
			title: '邮箱',
		},
		{
			field: 'status',
			title: '状态',
			slots: StatusColumnSolts,
		},
		{
			field: 'createTime',
			title: '创建时间',
		},
		{
			title: '操作',
			width: '150px',
			fixed: 'right',
			showOverflow: false,
			slots: { default: 'row-operate' },
		},
	],
	/** 数据代理配置项（基于 Promise API） */
	proxyConfig: {
		/** 启用动态序号代理 */
		seq: true,
		/** 是否代理表单 */
		form: true,
		/** 是否自动加载，默认为 true */
		// autoLoad: false,
		props: {
			total: 'total',
		},
		ajax: {
			query: ({ page, form }) => {
				xGridOpt.loading = true;
				crudStore.clearTable();
				return new Promise((resolve) => {
					let total = 0;
					let result: RowMeta[] = [];
					/** 加载数据 */
					const callback = (res: GetTableResponseData) => {
						if (res?.data) {
							// 总数
							total = res.data.total;
							// 列表数据
							result = res.data.list;
						}
						xGridOpt.loading = false;
						// 返回值有格式要求，详情见 vxe-table 官方文档
						resolve({ total, result });
					};

					/** 接口需要的参数 */
					const params = {
						username: form.username || undefined,
						phone: form.phone || undefined,
						size: page.pageSize,
						currentPage: page.currentPage,
					};
					/** 调用接口 */
					getTableDataApi(params).then(callback).catch(callback);
				});
			},
		},
	},
});
//#endregion

//#region vxe-modal
const xModalDom = ref<VxeModalInstance>();
const xModalOpt: VxeModalProps = reactive({
	title: '',
	showClose: true,
	escClosable: true,
	maskClosable: true,
	beforeHideMethod: () => {
		xFormDom.value?.clearValidate();
		return Promise.resolve();
	},
});
//#endregion

//#region vxe-form
const xFormDom = ref<VxeFormInstance>();
const xFormOpt: VxeFormProps = reactive({
	span: 24,
	titleWidth: '100px',
	loading: false,
	/** 是否显示标题冒号 */
	titleColon: false,
	/** 表单数据 */
	data: {
		username: '',
		password: '',
	},
	/** 项列表 */
	items: [
		{
			field: 'username',
			title: '用户名',
			itemRender: { name: '$input', props: { placeholder: '请输入' } },
		},
		{
			field: 'password',
			title: '密码',
			itemRender: { name: '$input', props: { placeholder: '请输入' } },
		},
		{
			align: 'right',
			itemRender: {
				name: '$buttons',
				children: [
					{ props: { content: '取消' }, events: { click: () => xModalDom.value?.close() } },
					{
						props: { type: 'submit', content: '确定', status: 'primary' },
						events: { click: () => crudStore.onSubmitForm() },
					},
				],
			},
		},
	],
	/** 校验规则 */
	rules: {
		username: [
			{
				required: true,
				validator: ({ itemValue }) => {
					switch (true) {
						case !itemValue:
							return new Error('请输入');
						case !itemValue.trim():
							return new Error('空格无效');
					}
				},
			},
		],
		password: [
			{
				required: true,
				validator: ({ itemValue }) => {
					switch (true) {
						case !itemValue:
							return new Error('请输入');
						case !itemValue.trim():
							return new Error('空格无效');
					}
				},
			},
		],
	},
});
//#endregion

//#region 增删改查
const crudStore = reactive({
	/** 表单类型，true 表示修改，false 表示新增 */
	isUpdate: true,
	/** 加载表格数据 */
	commitQuery: () => xGridDom.value?.commitProxy('query'),
	/** 清空表格数据 */
	clearTable: () => xGridDom.value?.reloadData([]),
	/** 点击显示弹窗 */
	onShowModal: (row?: RowMeta) => {
		if (row) {
			crudStore.isUpdate = true;
			xModalOpt.title = '修改用户';
			// 赋值
			xFormOpt.data.username = row.username;
		} else {
			crudStore.isUpdate = false;
			xModalOpt.title = '新增用户';
		}
		// 禁用表单项
		const props = xFormOpt.items?.[0]?.itemRender?.props;
		props && (props.disabled = crudStore.isUpdate);
		xModalDom.value?.open();
		nextTick(() => {
			!crudStore.isUpdate && xFormDom.value?.reset();
			xFormDom.value?.clearValidate();
		});
	},
	/** 确定并保存 */
	onSubmitForm: () => {
		if (xFormOpt.loading) return;
		xFormDom.value?.validate((errMap) => {
			if (errMap) return;
			xFormOpt.loading = true;
			const callback = () => {
				xFormOpt.loading = false;
				xModalDom.value?.close();
				ElMessage.success('操作成功');
				!crudStore.isUpdate && crudStore.afterInsert();
				crudStore.commitQuery();
			};
			if (crudStore.isUpdate) {
				// 模拟调用修改接口成功
				setTimeout(() => callback(), 1000);
			} else {
				// 模拟调用新增接口成功
				setTimeout(() => callback(), 1000);
			}
		});
	},
	/** 新增后是否跳入最后一页 */
	afterInsert: () => {
		const pager = xGridDom.value?.getProxyInfo()?.pager;
		if (pager) {
			const currentTotal = pager.currentPage * pager.pageSize;
			if (currentTotal === pager.total) {
				++pager.currentPage;
			}
		}
	},
	/** 删除 */
	onDelete: (row: RowMeta) => {
		const tip = `确定 <strong style="color: var(--el-color-danger);"> 删除 </strong> 用户 <strong style="color: var(--el-color-primary);"> ${row.username} </strong> ？`;
		const config: ElMessageBoxOptions = {
			type: 'warning',
			showClose: true,
			closeOnClickModal: true,
			closeOnPressEscape: true,
			cancelButtonText: '取消',
			confirmButtonText: '确定',
			dangerouslyUseHTMLString: true,
		};
		ElMessageBox.confirm(tip, '提示', config).then(() => {
			deleteTableDataApi(row.id).then(() => {
				ElMessage.success('删除成功');
				crudStore.afterDelete();
				crudStore.commitQuery();
			});
		});
	},
	/** 删除后是否返回上一页 */
	afterDelete: () => {
		const tableData: RowMeta[] = xGridDom.value!.getData();
		const pager = xGridDom.value?.getProxyInfo()?.pager;
		if (pager && pager.currentPage > 1 && tableData.length === 1) {
			--pager.currentPage;
		}
	},
	/** 更多自定义方法 */
	moreFn: () => {},
});
//#endregion
</script>

<template>
	<div class="app-container">
		<!-- 表格 -->
		<vxe-grid ref="xGridDom" v-bind="xGridOpt">
			<!-- 左侧按钮列表 -->
			<template #toolbar-btns>
				<vxe-button status="primary" icon="vxe-icon-add" @click="crudStore.onShowModal()">新增用户</vxe-button>
				<vxe-button status="danger" icon="vxe-icon-delete">批量删除</vxe-button>
			</template>
			<!-- 操作 -->
			<template #row-operate="{ row }">
				<el-button link type="primary" @click="crudStore.onShowModal(row)">修改</el-button>
				<el-button link type="danger" @click="crudStore.onDelete(row)">删除</el-button>
			</template>
		</vxe-grid>
		<!-- 弹窗 -->
		<vxe-modal ref="xModalDom" v-bind="xModalOpt">
			<!-- 表单 -->
			<vxe-form ref="xFormDom" v-bind="xFormOpt" />
		</vxe-modal>
	</div>
</template>
